#include "hashSet.h"

#include <stdlib.h>
#include <time.h>
#include <string.h>

// 哈希函数
static uint32_t hash(const void *key, int len, uint32_t seed)
{
    const uint32_t m = 0x5bd1e995;
    const int r = 24;
    uint32_t h = seed ^ len;
    const unsigned char *data = (const unsigned char *)key;

    while (len >= 4)
    {
        uint32_t k = *(uint32_t *)data;
        k *= m;
        k ^= k >> r;
        k *= m;
        h *= m;
        h ^= k;
        data += 4;
        len -= 4;
    }

    switch (len)
    {
    case 3:
        h ^= data[2] << 16;
    case 2:
        h ^= data[1] << 8;
    case 1:
        h ^= data[0];
        h *= m;
    };

    h ^= h >> 13;
    h *= m;
    h ^= h >> 15;

    return h;
}

system_error_code_t hash_set_init(hash_set_t *set, int size)
{
    // 参数检查
    if (set == NULL || size <= 0)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT; // 参数无效
    }

    // 初始化底层哈希表
    system_error_code_t ret = hash_map_init(&set->map, size);
    if (ret != SYSTEM_ERR_OK)
    {
        return ret; // 返回哈希表初始化结果
    }

    return SYSTEM_ERR_OK; // 初始化成功
}

system_error_code_t hash_set_put(hash_set_t *set, int fd)
{
    // 参数检查
    if (set == NULL)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT; // 参数无效
    }

    // 尝试插入文件描述符到底层哈希表
    return hash_map_put(&set->map, fd, 0); // 环形队列索引设为0占位
}

system_error_code_t hash_set_remove(hash_set_t *set, int fd)
{
    // 参数检查
    if (set == NULL)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT; // 参数无效
    }

    // 从底层哈希表中移除指定文件描述符
    return hash_map_remove(&set->map, fd);
}

system_error_code_t hash_set_get_all_fds(hash_set_t *set, int **out_fds)
{
    // 参数检查
    if (set == NULL || out_fds == NULL)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT; // 参数无效
    }

    int count = set->map.count;
    if (count == 0)
    {
        *out_fds = NULL;
        return SYSTEM_ERR_OK;
    }

    // 为文件描述符数组分配内存
    int *fd_array = (int *)malloc(sizeof(int) * count);
    if (fd_array == NULL)
    {
        return SYSTEM_ERR_OUT_OF_MEMORY; // 内存分配失败
    }

    // 获取所有文件描述符
    int index = 0;
    for (int i = 0; i < set->map.size; i++)
    {
        hash_node_t *node = set->map.buckets[i];
        while (node != NULL)
        {
            if (index < count)
            {
                fd_array[index] = node->fd;
                index++;
            }
            node = node->next;
        }
    }
    *out_fds = fd_array;

    return SYSTEM_ERR_OK; // 获取成功
}

system_error_code_t hash_set_clear(hash_set_t *set)
{
    // 参数检查
    if (set == NULL)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT; // 参数无效
    }

    // 清空底层哈希表
    for (int i = 0; i < set->map.size; i++)
    {
        hash_node_t *node = set->map.buckets[i];
        while (node != NULL)
        {
            hash_node_t *temp = node;
            node = node->next;
            free(temp);
        }
        set->map.buckets[i] = NULL;
    }
    set->map.count = 0;

    return SYSTEM_ERR_OK; // 清空成功
}